# -*- coding: utf-8 -*-

import threading

import logger
_log=logger.log

class _MyThread(threading.Thread):
    def __init__(self,func,*args,**kargs):
        threading.Thread.__init__(self,name=str(func))
        self.func=func
        self.args=args
        self.kargs=kargs
                
    def run(self):
        try:
            self.func(*self.args,**self.kargs)
        except Exception,e:
            _log.exception('sub thread error')


def runJob(func,*args,**kargs):
    """
    runJob(function func,*args,**kargs)
    
    在任务管理器中异步的运行一个Job,job就是传入的func定义的
    func参数是一个方法:
        func(...) 参数随意，runJob方法后面的参数都是func的参数，
         在线程运行时传给func
    """
    t=_MyThread(func,*args,**kargs)
    t.setDaemon(True)
    t.start()

class IMonitor(object):
    """
    示意接口
    
    Monitor作为core和ui部分的连接，一般用作ui观察core的运行
    """
    
    UNKNOWN_TOTAL_WORK = -1 #未知数量任务
    
    def beginTask( self,name, totalWork):
        '''
        beginTask(basestring name,int totalWork)
        '''

    def setTaskName(self,name):
        '''
        setTaskName(basestring name)
        '''

    def isCanceled():
        '''
        isCanceled() -> bool
        '''
        return False
    
    def worked(self,work):
        '''
        worked()
        '''

    def done(self):
        '''
        done()
        '''
        
    def internalWorked(self,work) :
        '''
        internalWorked(float work)
        
         由子monitor向上报告实际工作情况
        '''
        
class DefaultMonitor (IMonitor):
    """IMonitor的缺省实现"""

class SubMonitor(IMonitor):
    def __init__(self,parentMonitor,parentTicks):
        self.parentMonitor = parentMonitor
        self.parentTicks = parentTicks # parent monitor给我们了多少点tick供我们挥霍
        self.scale = 0.0
        self.sentToParent = 0.0
        
    #override IMonitor
    def beginTask( self,name, totalWork):
        '''
        beginTask(basestring name,int myTicks)
        '''
        #todo only call once
        self.scale = self.parentTicks / float(totalWork)

        
    #override IMonitor
    def done(self):
        '''
        done()
        '''
        #only call once ,and must called begin
        self.parentMonitor.internalWorked(self._remaining());
        
        
    def internalWorked(self,work) :
        if self._remaining() <= 0  :
            return 
        
        realWork = self.scale * work;
        self.parentMonitor.internalWorked(realWork);
        self.sentToParent += realWork;
    
    def _remaining(self):
        """
        _remaining() -> float
        
        parent monitor给我们了的tick还剩下多少供我们挥霍
        """
        return self.parentTicks - self.sentToParent
    
    #override IMonitor
    def setTaskName(self,name):
        '''
        setTaskName(basestring name)
        '''
        self.parentMonitor.setTaskName(name)
        
    #override IMonitor
    def isCanceled(self):
        '''
        isCanceled() -> bool
        '''
        return self.parentMonitor.isCanceled()
    
    #override IMonitor
    def worked(self,work):
        '''
        worked()
        '''
        self.internalWorked(work)


